/* phone.h */

/********************/
/* SPCORE-TELEPHONE */
/* handling calls   */
/* (C) 2003 by NAH6 */
/********************/

#ifndef __PHONE_H
#define __PHONE_H
#ifdef __cplusplus
extern "C" {
#endif

/*------------*/
/*  INCLUDES  */
/*------------*/

#include <windows.h>

#include "crypto.h"
#include "winaudio.h"
#include "winsio.h"
#include "hayes.h"
#include "wintapi.h"

/*-----------*/
/*  DEFINES  */
/*-----------*/

#define E_PHONE_NULLPTR      (-0x1101)
#define E_PHONE_NOMEM        (-0x1102)
#define E_PHONE_BADPHONE     (-0x1103)
#define E_PHONE_ISOFF        (-0x1104)
#define E_PHONE_NOCALL       (-0x1105)
#define E_PHONE_INUSE        (-0x1106)
#define E_PHONE_MODE         (-0x1107)
#define E_PHONE_INDEX        (-0x1108)
#define E_PHONE_CODEC        (-0x1109)
#define E_PHONE_SIZE         (-0x110A)
#define E_PHONE_FULL         (-0x110B)
#define E_PHONE_TELTHREAD    (-0x110C)
#define E_PHONE_TXEVENT      (-0x110D)
#define E_PHONE_RXTHREAD     (-0x110E)
#define E_PHONE_TXTHREAD     (-0x110F)

/*====*/

#define K_PHONE_MAXPHONES          (4)
#define K_PHONE_DIALNUMBUFLEN     (64)
#define K_PHONE_CHUNKBUFLEN      (128)
#define K_PHONE_ABLKSAMPLES      (256)
#define K_PHONE_UDCMSGLEN       (2044)
#define K_PHONE_UDCMSGCNT          (4)

#define K_PHONE_RINGTIMEOUT     (7000)
#define K_PHONE_IDLERESTIME      (500)
#define K_PHONE_TXCHECKTIME      (100)
#define K_PHONE_STDJITTER       (1000)
#define K_PHONE_MAXJITTER       (2000)
#define K_PHONE_JITTERCNT         (64)

#define K_PHONE_LINETYPE_HAYES     (0)
#define K_PHONE_LINETYPE_TAPI      (1)

/*----*/

#ifndef _WIN32_WCE  /*Win98=22,23 WinCE=249,248*/
  #define K_PHONE_TELPRIO    (THREAD_PRIORITY_LOWEST)
  #define K_PHONE_DSPPRIO    (THREAD_PRIORITY_BELOW_NORMAL)
#else
  #define K_PHONE_TELPRIO    (THREAD_PRIORITY_HIGHEST)
  #define K_PHONE_DSPPRIO    (THREAD_PRIORITY_TIME_CRITICAL)
#endif

/* Auto config type */
#define CFGTYPE_GSMTAPI           (0)
#define CFGTYPE_DESKTOP           (1)
#define CFGTYPE_GSMHAYES_COM2     (2)
#define CFGTYPE_POTSHAYES_COM1    (3)

/*--------------*/
/*  STRUCTURES  */
/*--------------*/

struct phone_tapicfg
{
  struct tapi_config tapi;
  struct sio_config  sio;
};

struct phone_tapiram
{
  struct tapi_data tapi;
  struct sio_data  sio;
};

/*--*/

union line_config
{
  struct hayes_config  hayes;
  struct phone_tapicfg tcfg;
};

union line_dseg
{
  struct hayes_data    hayes;
  struct phone_tapiram tram;
};

union line_link
{
  struct hayes_link hayes;
  struct tapi_link  tapi;
};

/*----*/

struct phone_link
{
  unsigned long jobid;
  unsigned char dialout;
  unsigned char service;
  unsigned char carrier;
  unsigned char protocol;
  unsigned long baudrate;
  unsigned char diallength;
  unsigned char dialstring[K_PHONE_DIALNUMBUFLEN];
};

/*====*/

struct phone_hwinfo
{
  struct audio_hwinfo ainfo;
  struct tapi_hwinfo  tinfo;
};

struct phone_config
{
  struct audio_hwconfig acfg;
  unsigned char         ltype;
  union  line_config    lcfg;
};

struct phone_protocol
{
  HANDLE                     rxthread;
  DWORD                      rxthreadid;
  HANDLE                     txthread;
  DWORD                      txthreadid;

  unsigned char              rxmode;
  unsigned char              rxcodecsel;
  unsigned char              rxcodectbl[2];
  unsigned char              rxcodecopen;
  unsigned char              rxchunklen;
  unsigned char              rxchunk[K_PHONE_CHUNKBUFLEN];
  signed short               rxaudio1[K_PHONE_ABLKSAMPLES];
  signed short               rxaudio2[(K_PHONE_ABLKSAMPLES * 5) / 4];
  void                      *rxcodecstate;
  unsigned short             rxjitval;
  unsigned char              rxjitcnt;
  unsigned short             rxjitmax;
  DWORD                      rxjittime;
  unsigned short             rxudclen;
  unsigned char              rxudcbuf[K_PHONE_UDCMSGLEN + 4];
  unsigned char              rxsyncstat;
  unsigned char              rxsyncidx;
  unsigned char              rxsyncesc;
  unsigned char              rxsyncbuf[67];
  unsigned long              rxcryptkey[8];
  unsigned long              rxcryptcnt[4];
  unsigned char              rxcryptbufpos;
  unsigned long              rxcryptbuf[4];
  struct crypto_tandem_state rxcrypt;
  struct crypto_sha_state    rxhash;

  unsigned char              txmode;
  unsigned char              txcodecsel;
  unsigned char              txcodectbl[2];
  unsigned char              txcodecopen;
  unsigned char              txchunk[K_PHONE_CHUNKBUFLEN];
  signed short               txaudio[K_PHONE_ABLKSAMPLES];
  void                      *txcodecstate;
  HANDLE                     txudcevt;
  unsigned char              txudcdada;
  unsigned char              txudcwrpos;
  unsigned char              txudcrdpos;
  unsigned short             txudcrdidx;
  unsigned long              txudcid [K_PHONE_UDCMSGCNT];
  unsigned short             txudclen[K_PHONE_UDCMSGCNT];
  unsigned char              txudcbuf[K_PHONE_UDCMSGCNT][K_PHONE_UDCMSGLEN + 4];
  unsigned long              txcryptkey[8];
  unsigned long              txcryptcnt[4];
  unsigned char              txcryptbufpos;
  unsigned long              txcryptbuf[4];
  struct crypto_tandem_state txcrypt;
  struct crypto_sha_state    txhash;
};

struct phone_dseg
{
  unsigned char          phone;
  volatile unsigned char sigterm;
  volatile unsigned char sighup;
  volatile unsigned char busy;
  unsigned char          ringing;
  DWORD                  lastring;
  struct phone_link      usrlink;
  struct phone_link      evtlink;
  union  line_link       link;

  struct phone_config    config;
  struct audio_dseg      adseg;
  union  line_dseg       ldseg;
  HANDLE                 telthread;
  DWORD                  telthreadid;

  CRITICAL_SECTION       plock[2];
  struct phone_protocol *proto;
};

struct phone_baseinfo
{
  CRITICAL_SECTION    slock;
  struct phone_config settings;
  CRITICAL_SECTION    dlock;
  struct phone_dseg  *dseg;
};

/*--------------*/
/*  PROTOTYPES  */
/*--------------*/

void phone_install (void);
void phone_remove  (void);

void phone_hwdetect_create  (struct phone_hwinfo *info);
void phone_hwdetect_destroy (const struct phone_hwinfo *info);

signed short phone_autoconfig (unsigned char phone, unsigned char cfgtype,
							   unsigned char mdmport, unsigned char mdmtype);
signed short phone_setconfig  (unsigned char phone, \
                               const struct phone_config *config);
signed short phone_getconfig  (unsigned char phone, \
                               struct phone_config *config);

signed short phone_on  (unsigned char phone);
signed short phone_off (unsigned char phone, signed short *retval);

signed short phone_hangup  (unsigned char phone);
signed short phone_connect (unsigned char phone, const struct phone_link *link);

signed short phone_setdecstate    (unsigned char phone,         \
                                   const unsigned char key[32], \
                                   const unsigned char cnt[16]);
signed short phone_getdecstate    (unsigned char phone, unsigned char key[32], \
                                   unsigned char cnt[16]);
signed short phone_setdecmode     (unsigned char phone, unsigned char mode);
signed short phone_getdecmode     (unsigned char phone);
signed short phone_setdeccodectbl (unsigned char phone, unsigned char index, \
                                   unsigned char codec);
signed short phone_getdeccodectbl (unsigned char phone, unsigned char codec[2]);
signed short phone_getdeccodec    (unsigned char phone);
signed short phone_getdecsync     (unsigned char phone);

signed short phone_setencstate    (unsigned char phone,         \
                                   const unsigned char key[32], \
                                   const unsigned char cnt[16]);
signed short phone_getencstate    (unsigned char phone, unsigned char key[32], \
                                   unsigned char cnt[16]);
signed short phone_setencmode     (unsigned char phone, unsigned char mode);
signed short phone_getencmode     (unsigned char phone);
signed short phone_setenccodectbl (unsigned char phone, unsigned char index, \
                                   unsigned char codec);
signed short phone_getenccodectbl (unsigned char phone, unsigned char codec[2]);
signed short phone_setenccodec    (unsigned char phone, unsigned char index);
signed short phone_getenccodec    (unsigned char phone);
signed short phone_userdata       (unsigned char phone, unsigned long id, \
                                   const void *data, unsigned short len);

/*-------------*/
/*  VARIABLEN  */
/*-------------*/

extern struct phone_baseinfo phone_base[K_PHONE_MAXPHONES];

#ifdef __cplusplus
}
#endif
#endif


/*** EOF ***/
